package genealogy.deprecated.datamodel.pedigree;

import genealogy.deprecated.datamodel.pedigree.visitors.IPedigreeVisitor;

import java.io.Serializable;
import java.util.HashMap;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
 * Date <BR>
 * Is a standardized date with month, day and year values
 */
@Deprecated
public class Date implements Serializable, IPedigreeVisitable {
	
	private static final long serialVersionUID = 5939416124868572391L;
	
	private static final Pattern monthPattern = Pattern.compile("jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec",Pattern.CASE_INSENSITIVE);		
	private static final Pattern yearPattern = Pattern.compile("\\d{4}");
	private static final Pattern dayPattern = Pattern.compile("\\d{2}\\s");
	
	public static final HashMap<String,Integer> monthNumbers = new HashMap<String,Integer>();
	static{
		monthNumbers.put("jan", 1);
		monthNumbers.put("feb", 2);
		monthNumbers.put("mar", 3);
		monthNumbers.put("apr", 4);
		monthNumbers.put("may", 5);
		monthNumbers.put("jun", 6);
		monthNumbers.put("jul", 7);
		monthNumbers.put("aug", 8);
		monthNumbers.put("sep", 9);
		monthNumbers.put("oct", 10);
		monthNumbers.put("nov", 11);
		monthNumbers.put("dec", 12);
	}
	
	private static final String[] months 
		= new String[]{"JAN", "FEB", "MAR", "APR", "MAY", "JUN", "JUL", "AUG", "SEP", "OCT", "NOV", "DEC"};
	

	/**
	 * holds the day value (Must be from 1 and 31. 0 means NULL)
	 */
	protected int day;
	
	/**
	 * holds the month value (Must be from 1 and 12. 0 means NULL)
	 */
	protected int month;
	
	/**
	 * holds the year value (Must be from 1 and 2050. 0 means NULL)
	 */
	protected int year;

	/**
	 * Default Constructor.
	 */
	public Date() {
		this.day = 0;
		this.month = 0;
		this.year = 0;
	}
	
	/**
	 * Constructor
	 * 
	 * @param dateString formatted like gedcom: Example 04 APR 2007
	 */
	public Date(String dateString) {

	
		Matcher yearMatcher = yearPattern.matcher(dateString);
		Matcher dayMatcher = dayPattern.matcher(dateString);
		Matcher monthMatcher = monthPattern.matcher(dateString);
		
		if(yearMatcher.find()) 
			this.year = Integer.parseInt(yearMatcher.group());
		if(monthMatcher.find()){
			String month = monthMatcher.group().toLowerCase();
			this.month = monthNumbers.get(month);
		}
		if(dayMatcher.find()){
			String day = dayMatcher.group().trim();
			this.day = Integer.parseInt(day);
		}
	}
	/**
	 * @param day The day of the month (Ex: 21 for April 21st)
	 * @param month The month of the year (Ex: 4 for April 21st)
	 * @param year The year (Ex: 1981)
	 */
	public Date(int day, int month, int year) {
		setDay(day);
		setMonth(month);
		setYear(year);
	}
	
	public int getInternallNumber(){
		return year * 10000 + month * 100 + day;
	}
	
	/**
	 * @return Returns the day.
	 */
	public int getDay() {
		return day;
	}
	/**
	 * @param day The day to set.
	 */
	public void setDay(int day) {
		assert( (day >= 0) && (day <= 31) );
		this.day = day;
	}
	/**
	 * @return Returns the month.
	 */
	public int getMonth() {
		return month;
	}
	/**
	 * @param month The month to set.
	 */
	public void setMonth(int month) {
		assert( (month >= 0) && (month <= 12) );
		this.month = month;
	}
	/**
	 * @return Returns the year.
	 */
	public int getYear() {
		// assert( (year >= 0) && (year <= 2050) );
		return year;
	}
	/**
	 * @param year The year to set.
	 */
	public void setYear(int year) {
		this.year = year;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see java.lang.Object#toString()
	 */	
	public String toString(){
		String s = "";
		s += (day != 0)? dayToString()+" " : "";
		s += (month != 0)? getThreeCharMonth(month) + " " : "";
		s += (year != 0)? year + "\n" : "";
		return s;
	}

	public String dayToString(){
		String dayString = "";
		if (day == 0) return "";
		if(day < 10){
			dayString+= "0";
		}
		return dayString+= day;
	}
	
	public String yearToString(){
		return Integer.toString(year);
	}
	
	
	public String getThreeCharMonth(int month){
		if(month < 1 || month > 12 ) return "";
		return months[month - 1];
	}
	
	public int getNumberOfParts(){
		int parts = 0;
		parts += (day != 0)? 1  : 0;
		parts += (month != 0)? 1  : 0;
		parts += (year != 0)? 1  : 0;
		return parts;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	@Override
	public boolean equals(Object arg0) {
		if(arg0 instanceof Date){
			Date d = (Date) arg0;
			return this.toString().equalsIgnoreCase(d.toString());
		}
		return false;
	}
	
	/*
	 * (non-Javadoc)
	 * 
	 * @see genealogy.datamodel.pedigree.IPedigreeVisitable#accept(genealogy.datamodel.pedigree.visitors.AbstractPedigreeVisitor)
	 */
	public void accept(IPedigreeVisitor visitor) {
		visitor.visit(this);
		visitor.endVisit();
	}
}
